package com.sjs.boot.dynamic.facade.config;

import com.sjs.boot.dynamic.core.config.method.MethodConfig;
import com.sjs.boot.dynamic.core.config.method.parameter.ParameterInfo;
import com.sjs.boot.dynamic.facade.run.AbstractHandler;
import com.sjs.boot.dynamic.facade.run.AbstractRequester;
import com.sjs.boot.dynamic.util.ValParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author uto_dev_008
 * @desc
 * @since 2021/11/9 19:24
 * Copyright (c) 2021 南京友拓信息技术有限公司 All rights reserved
 */
public abstract class AbstractRequestConfig {
    private static final Logger LOG = LoggerFactory.getLogger(AbstractRequestConfig.class);
    private static final String CONFIG_PARAMETERS = "parameters";
    private static final String CONFIG_SIGN = "sign"; //接口的参数是否需要校验签名

    private ParameterInfo[] parameters = new ParameterInfo[0];
    private Map<String, ParameterInfo> mapParameters = new HashMap<String, ParameterInfo>();
    private ParameterInfo[] responseParameters = null; //需要放入响应的请求参数
    private boolean sign = false;

    abstract protected boolean parseExt(String version, Map<String, Object> json, MethodConfig mc);

    public boolean parse(String version, Map<String, Object> json, MethodConfig mc) {
        if (json == null) {
            return true; //使用默认的配置
        }

        AbstractRequester processor = (AbstractRequester) AbstractHandler.getHandler(json, mc.getRequester());
        if (processor == null) {
            LOG.error("Fail to read requester-processor of {}", mc.getName());
            return false;
        }
        mc.setRequester(processor);

        if (json.containsKey(CONFIG_PARAMETERS)) {
            List<Object> arr = ValParser.getAsList(json, CONFIG_PARAMETERS);
            ParameterInfo para;

            int no = 0;
            int index = 1;
            List<ParameterInfo> responseParamrs = new ArrayList<ParameterInfo>();
            this.parameters = new ParameterInfo[arr.size()];

            for (Object o : arr) {
                if (!(o instanceof Map<?, ?>)) {
                    LOG.error("Invalid parameter config");
                    return false;
                }

                if ((para = ParameterInfo.parse(version, (Map<String, Object>) o, mc, index)) == null) {
                    LOG.error("Fail to parse parameter information");
                    return false;
                }

                //如果设置了index<=0，则index不用递增
                if (para.getIndex() > 0) {
                    index++;
                }

                this.parameters[no++] = para;
                if (para.response()) {
                    responseParamrs.add(para);
                }

                this.mapParameters.put(para.getName(), para);
            }

            if (responseParamrs.size() > 0) {
                this.responseParameters = responseParamrs.toArray(new ParameterInfo[0]);
            }
        }
        this.sign = ValParser.getAsBool(json, CONFIG_SIGN, this.sign);

        return parseExt(version, json, mc);
    }

    /**
     * 获得所有的参数列表，与配置的顺序一致
     *
     * @return
     */
    public ParameterInfo[] getParameters() {
        return parameters;
    }

    /**
     * 根据参数名称获得参数相关的配置信息
     *
     * @param name
     * @return
     */
    public ParameterInfo getParameter(String name) {
        return mapParameters.get(name);
    }

    /**
     * 放入响应信息的字段列表
     *
     * @return
     */
    public ParameterInfo[] getResponseParameters() {
        return responseParameters;
    }

    /**
     * 接口是否需要签名，如果需要签名，context中可以获取到原始参数列表
     *
     * @return
     */
    public boolean isSign() {
        return sign;
    }

    //override it when need it
    public void destroy() {
    }
}
